package com.bxj.wxtt.filter;

import com.bxj.wxtt.log.LogFileName;
import com.bxj.wxtt.log.LoggerUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service("sessionFilter")
public class SessionFilter implements Filter {
    private static final String SYSTEM_MAINTENANCE_PAGE = "/system_maintenance.html";
    private static int count = 0;

    /* 系统处于维护模式 */
    public static boolean SYSTEM_MAINTENANCE = false;
    private static String LOG_VERSION = "3";
    Logger access_log = LoggerUtils.getLogger(LogFileName.ACCESS_LOG);

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            String uri = ((HttpServletRequest) request).getRequestURI();
            int i = uri.lastIndexOf(".");
            if ((i > 0) && (uri.length() - i > 2)) {
                String ext = uri.substring(i);
                if (ext.equals(".jpg")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".jsp")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".js")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".gif")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".html")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".css")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".png")) {
                    chain.doFilter(request, response);
                    return;
                }
                if (ext.equals(".ico")) {
                    chain.doFilter(request, response);
                    return;
                }
            }

            try {
                if (SYSTEM_MAINTENANCE) {
                    ((HttpServletResponse) response).sendRedirect(SYSTEM_MAINTENANCE_PAGE);
                }
            } catch (Exception e2) {
//                LogHelper.exceptionLog(e2);
            }
            //请求开始时间
            long beginTimePoint = System.currentTimeMillis();
            String requestBeginTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(beginTimePoint));

            ClientInfo clientInfo = getClientInfo((HttpServletRequest) request);
            request.setAttribute("clientInfo", clientInfo);


            int c = count++;
            System.out
                    .println(">>>>11>>>>>>>> " + c + "\t" + requestBeginTime + " 开始 " + ((HttpServletRequest) request)
                            .getRequestURL());// + UrlUtils.getDecodeParams((HttpServletRequest) request));
            String ext = FilenameUtils.getExtension(uri);
            if (isGZipEncoding(request)) {
                //需要过滤的扩展名：.htm,.html,.jsp,.js,.ajax,.css
                String gzippPattern = ",.htm,.html,.jsp,.js,.ajax,.css,";
                if (StringUtils.indexOf(gzippPattern, ",." + ext + ",") != -1) {
                    BufferedResponse gzipResponse = new BufferedResponse(response);
                    chain.doFilter(request, gzipResponse);
                    byte[] srcData = gzipResponse.getResponseData();
                    byte[] outData = null;
                    if (srcData.length > 512) {
                        byte[] gzipData = ZipUtil2.compress(srcData);
                        response.addHeader("Content-Encoding", "gzip");
                        response.setContentLength(gzipData.length);
                        outData = gzipData;
                    } else {
                        outData = srcData;
                    }
                    ServletOutputStream output = response.getOutputStream();
                    output.write(outData);
                    output.flush();
                } else {
                    chain.doFilter(request, response);
                }
            } else {
                chain.doFilter(request, response);
            }
//            //请求结束时间
            long endTimePoint = System.currentTimeMillis();
            String requestEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(endTimePoint));
            double d = endTimePoint - beginTimePoint;
            request.setAttribute("second", Double.toString(d / 1000)); // 耗时

            String requestLog = getRequestLog((HttpServletRequest) request, response, requestBeginTime, requestEndTime);
            access_log.info(requestLog);

            System.out.println(">>>>22>>>>>>>> " + c + "\t" + requestEndTime + " 结束 " + ((HttpServletRequest) request)
                    .getRequestURL());// + UrlUtils.getDecodeParams((HttpServletRequest)request));
        } catch (Exception e) {
            throw e;
//            LogHelper.exceptionLog(e);
//            try {
//                ((HttpServletResponse) response).sendRedirect(SYSTEM_MAINTENANCE_PAGE);
//                return;
//            } catch (Exception e2) {
//                LogHelper.exceptionLog("重定向至系统维护页面时异常", e2);
//            }
        }
    }

    /**
     * 判断浏览器是否支持GZIP
     *
     * @param request
     * @return
     */
    private boolean isGZipEncoding(HttpServletRequest request) {
        boolean flag = false;
        String encoding = request.getHeader("Accept-Encoding");
        if (encoding.indexOf("gzip") != -1) {
            flag = true;
        }
        return flag;
    }

    private ClientInfo getClientInfo(HttpServletRequest request) {
        ClientInfo clientInfo = new ClientInfo();
//		clientInfo.setSessionid("0f08549b85e84f64b974cc96cc7660ce");// 该sesionid在开发库的过期时间为2015年12月
//        clientInfo.setSessionid(CookieUtils.getCookieValue(request, "sessionid"));
//        clientInfo.setUser(FacadeRepository.userProfileFacade.getLoginUserProfiles(clientInfo.getSessionid()));
//		clientInfo.setxClient(FacadeRepository.clientInfoHelper.getXClient(request.getRequestURL().toString(),
//				TdcnUtil.getParameter(request), request.getHeader("X-Client")));
        clientInfo.setxClient(request.getHeader("X-Client"));
        Map<String, String> xClientMap = getXClientMap(clientInfo.getxClient());

        clientInfo.setPhoneModel(xClientMap.get("pm"));
        clientInfo.setImei(xClientMap.get("imei"));
        clientInfo.setImsi(xClientMap.get("imsi"));
        clientInfo.setMac(xClientMap.get("mac"));
        clientInfo.setScreenSize(xClientMap.get("ss"));
        clientInfo.setSystemVersion((xClientMap.get("sv")));

//        // 兼容api4(android2.7)以前的版本
//        if (StringUtils.isEmpty(clientInfo.getSystemVersion())) {
//            clientInfo.setSystemVersion(xClientMap.get("sdk"));
//        }
//        if (StringUtils.isEmpty(clientInfo.getPhoneModel())) {
//            clientInfo.setPhoneModel(xClientMap.get("type"));
//        }
//
//        clientInfo.setCellId(xClientMap.get("cell_id"));
//        clientInfo.setRootPath(xClientMap.get("rootPath"));
//        clientInfo.setRn(xClientMap.get("rn"));
//        clientInfo.setTdcn(xClientMap.get("tdcn"));
        clientInfo.setVisitor(xClientMap.get("username"));

//        clientInfo.setSkin(xClientMap.get("skin"));
//        if (StringUtils.isEmpty(clientInfo.getSkin()) || "default".equalsIgnoreCase(clientInfo.getSkin())) {
//            if (StringUtils.isNotEmpty(request.getHeader("Api-Skin"))) {
//                clientInfo.setSkin(request.getHeader("Api-Skin"));
//            } else {
//                if (StringUtils.isNotEmpty(request.getParameter("apiSkin")) && (!("?".equals(request
//                        .getParameter("apiSkin")))) && (!("null".equals(request.getParameter("apiSkin"))))) {
//                    clientInfo.setSkin(request.getParameter("apiSkin"));
//                }
//            }
//        }

        Map<String, Object> versionMap = getVersionMap(xClientMap.get("version"), request);
        clientInfo.setVersion((String) versionMap.get("version"));
        clientInfo.setMainVersion((Integer) versionMap.get("mainVersion"));
        clientInfo.setSubVersion((Integer) versionMap.get("subVersion"));
        clientInfo.setChannel((Integer) versionMap.get("channel"));

        Integer platformId = (Integer) versionMap.get("platformId");
        //TODO 待确认如下处理是否合适
//        if (platformId == null) {
//            platformId = PlatformConstant.android.getId();//set default platfrom id for webbroswer
//        }
//        clientInfo.setPlatformId(platformId);
//        if (platformId != null) {
//            clientInfo.setPlatformGroupId(PlatformConstant.valueOf(platformId).getPlatformGroup().getId());
//        }

        // 获取大网sid，添加到clientInfo中
        String sid = request.getParameter("sid");
        if (StringUtils.isNotBlank(sid)) {
//            clientInfo.setSid(sid);
        }
        return clientInfo;
    }

    /**
     * 组装访问日志
     *
     * @param req
     * @param wrapper
     * @param requestEndTime
     * @param requestBeginTime
     * @return
     */
    private String getRequestLog(HttpServletRequest req, HttpServletResponse wrapper,
                                 String requestBeginTime, String requestEndTime) {

        try {
            final ClientInfo clientInfo = (ClientInfo) req.getAttribute("clientInfo");
//            final UserProfile user = clientInfo.getUser();
            //日志版本号
            String logVersion = "lv:" + LOG_VERSION;
            //项目名
            String projectName = "api";
            //日志服务器的IP
            String localIp = "";
//            if (ConfigBuilderFactory.getConfigBuilder().getProperty("local.host.ip") != null) {
//                localIp = ConfigBuilderFactory.getConfigBuilder().getProperty("local.host.ip");
//            }
            //请求耗时
            String second = (String) req.getAttribute("second");
            if (StringUtils.isEmpty(second)) {
                second = "";
            }
            //请求发起IP
            String ip = "";//IPUtils.getIpAddr(req);
            //请求的URL
            String at = req.getRequestURI();
            if (req.getQueryString() != null) {
                at += "?" + req.getQueryString();
            }
            //前一页URL
            String referer = req.getHeader("referer");
            if (StringUtils.isEmpty(referer)) {
                referer = "";
            }
            //请求方式
            String req_method = "GET";
            if ("post".equals(req.getMethod().toLowerCase())) {
                req_method = "POST";
            }
            //请求状态码
            int status = wrapper.getStatus();
            //用户ID
            String userid = "";
//            if (user != null) {
//                if (user.getId() != null) {
//                    userid = user.getId().toString();
//                }
//            }
            //SessionID
            String sessionId = clientInfo.getSessionid();
            if (StringUtils.isEmpty(sessionId)) {
                sessionId = "";
            }
            //平台 ID
            String platform = "";
            if (clientInfo.getPlatformId() != null) {
                platform = clientInfo.getPlatformId().toString();
            }
            //版本号
            Integer subVersion = clientInfo.getSubVersion();
            String version = "";
            if (subVersion != null) {
                if (subVersion < 10) {
                    version = clientInfo.getMainVersion() + "." + "0" + clientInfo.getSubVersion();
                } else {
                    version = clientInfo.getMainVersion() + "." + clientInfo.getSubVersion();
                }
            }
            //渠道ID
            String from = "";
            if (clientInfo.getChannel() != null) {
                from = String.valueOf(clientInfo.getChannel());
            }
            if (StringUtils.isEmpty(from)) {
//                from = CookieUtils.getCookieValue(req, "cid");
            }
            if (StringUtils.isEmpty(from)) {
                from = "";
            }
            //图书推荐展示
            String recommend = "";
            //消费类型
            String payType = (String) req.getAttribute("payType");
            if (payType == null) {
                payType = "";
            }

            //消费书币
            String payTadou = (String) req.getAttribute("payTadou");
            if (payTadou == null) {
                payTadou = "";
            }
            //充值方式
            String rechargeType = (String) req.getAttribute("rechargeType");
            if (rechargeType == null) {
                rechargeType = "";
            }
            //充值金额
            String rechargeAmount = (String) req.getAttribute("rechargeAmount");
            if (rechargeAmount == null) {
                rechargeAmount = "";
            }
            //SSID 写入游客用户名密码
            String SSID = clientInfo.getVisitor();
            //新老用户
            String noro = "";
            //渠道新老用户
            String c_noro = "";
            //阅读类型字数(分页)
            String per_page = "";
            //实际阅读字数
            String wordcount = "";
            Integer word_count = (Integer) req.getAttribute("word_count");
            if (word_count != null) {
                wordcount = word_count.toString();
                per_page = "";//CookieUtils.getCookieValue(req, "per_page");
                if (StringUtils.isEmpty(per_page)) {
                    per_page = "1500";
                }
            }
            //品牌|型号
            String uamobile = "";//CookieUtils.getCookieValue(req, "uamobile");
            if (StringUtils.isEmpty(uamobile)) {
                uamobile = "";
            }
            //下载平台
            String uaplatform = "";//CookieUtils.getCookieValue(req, "uaplatform");
            if (StringUtils.isEmpty(uaplatform)) {
                uaplatform = "";
            }
            //是否修改过ua
            String uastat = "";//CookieUtils.getCookieValue(req, "uastat");
            if (StringUtils.isEmpty(uastat)) {
                uastat = "";
            }
            //apiCode码
            Integer apiCode = (Integer) req.getAttribute("apiCode");
            //X-Client
            String xClient = clientInfo.getxClient();
            if (xClient == null) {
                xClient = "";
            }
            //UA
            String ua = req.getHeader("User-Agent");
            if (StringUtils.isEmpty(ua)) {
                ua = "";
            }
            //请求参数
            String paramsJson = "";//LogHelper.requestParamsJson(req);
            //34.处理参数
            String processingParamsJson = (String) req.getAttribute("processingParams");
            if (StringUtils.isEmpty(processingParamsJson)) {
                processingParamsJson = "";
            }
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            sb.append(logVersion);
            sb.append("] [");
            sb.append(projectName);
            sb.append("] [");
            sb.append(localIp);
            sb.append("] [");
            sb.append(requestBeginTime);
            sb.append("] [");
            sb.append(requestEndTime);
            sb.append("] [");
            sb.append(second);
            sb.append("] [");
            sb.append(ip);
            sb.append("] [");
            sb.append(at);
            sb.append("] [");
            sb.append(referer);
            sb.append("] [");
            sb.append(req_method);
            sb.append("] [");
            sb.append(status);
            sb.append("] [");
            sb.append(userid);
            sb.append("] [");
            sb.append(sessionId);
            sb.append("] [");
            sb.append(platform);
            sb.append("] [");
            sb.append(version);
            sb.append("] [");
            sb.append(from);
            sb.append("] [");
            sb.append(recommend);
            sb.append("] [");
            sb.append(payType);
            sb.append("] [");
            sb.append(payTadou);
            sb.append("] [");
            sb.append(rechargeType);
            sb.append("] [");
            sb.append(rechargeAmount);
            sb.append("] [");
            sb.append(SSID);
            sb.append("] [");
            sb.append(noro);
            sb.append("] [");
            sb.append(c_noro);
            sb.append("] [");
            sb.append(per_page);
            sb.append("] [");
            sb.append(wordcount);
            sb.append("] [");
            sb.append(uamobile);
            sb.append("] [");
            sb.append(uaplatform);
            sb.append("] [");
            sb.append(uastat);
            sb.append("] [");
            sb.append(apiCode);
            sb.append("] [");
            sb.append(xClient);
            sb.append("] [");
            sb.append(ua);
            sb.append("] [");
            sb.append(paramsJson);
            sb.append("] [");
            sb.append(processingParamsJson);
            sb.append("]");
            return sb.toString();
        } catch (Exception e) {
//            LogHelper.exceptionLog(e);
        }
        return null;

    }

    //
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }
//
    private Map<String, String> getXClientMap(String xClient) {
        HashMap<String, String> map = new HashMap<String, String>();
        if (xClient != null) {
            String[] infoArray = xClient.split(";");
            for (int i = 0; i < infoArray.length; i++) {
                String[] items = infoArray[i].split("=");
                if (items.length > 1) {
                    map.put(items[0], items[1]);
                } else if (items.length == 1) {
                    map.put(items[0], "");
                }
            }
        }
        return map;
    }
//
    private Map<String, Object> getVersionMap(String xClientVersion, HttpServletRequest request) {
        final HashMap<String, Object> map = new HashMap<String, Object>();
        String version = xClientVersion;

        if (version == null) {
            version = request.getParameter("ver");
        }

        if (version == null) {
            version = request.getParameter("v");
        }

        if (version == null) {
            return map;
        }

        // TODO 为了兼容某些带v=android/symbian参数的地方，暂时将其统一处理为低版本客户端
        if ("android".equals(version)) {
            version = "1.1.00.0";
        } else if ("symbian".equals(version)) {
            version = "2.1.00.0";
        }

        Pattern versionPatter = Pattern.compile("(\\d+).(\\d+).(\\d+).(\\d+)$");
        Matcher m = versionPatter.matcher(version);
        if (m.find()) {
            map.put("version", version);
            map.put("platformId", Integer.valueOf(m.group(1)));
            map.put("mainVersion", Integer.valueOf(m.group(2)));
            map.put("subVersion", Integer.valueOf(m.group(3)));
            map.put("channel", Integer.valueOf(m.group(4)));
        }

        return map;
    }

}
